package com.onesports.intelligent.k12.polarlight.security;

import com.onesports.intelligent.k12.polarlight.constant.SystemCodeConstants;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.Account;
import com.onesports.intelligent.k12.polarlight.domain.vo.auth.DataPermissionVO;
import com.onesports.intelligent.k12.polarlight.service.sys.AccountService;
import com.onesports.intelligent.k12.polarlight.service.sys.DataScopeService;
import com.onesports.intelligent.k12.polarlight.service.sys.ResourceService;
import com.onesports.intelligent.k12.polarlight.service.sys.RoleService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Authenticate a user from the database.
 */
@Component("userDetailsService")
public class DomainUserDetailsService implements UserDetailsService {

    private final Logger log = LoggerFactory.getLogger(DomainUserDetailsService.class);

    @Resource
    private AccountService accountService;
    @Resource
    private ResourceService resourceService;
    @Resource
    private RoleService roleService;
    @Resource
    private DataScopeService dataScopeService;

    @Override
    public UserDetails loadUserByUsername(final String login) {
        log.debug("Authenticating {}", login);
        String[] usernameAndOrigin = StringUtils.split(
                login, "-");
        String phone = usernameAndOrigin[0];
        String systemCode = usernameAndOrigin[1];
        Account user = null;

        // 不同端查询用户方式不同，运营需通过默认机构id查询
        if (SystemCodeConstants.OPERATION.equals(systemCode)) {
            user = accountService.getOperationAccount(phone);
            if (user == null) {
                throw new UsernameNotFoundException("用户名或密码错误");
            }
        } else if (SystemCodeConstants.ORGANIZATION.equals(systemCode)) {
            user = verifyOrganization(phone);
        }
        if(!user.getStatus()){
            throw new UsernameNotFoundException("当前用户已经被停用!");
        }
        return createUserDetails(user, systemCode);
    }

    public DomainUserDetails createUserDetails(Account user, String systemCode) {
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        List<String> orgIds = new ArrayList<>();
        List<String> campusIds = new ArrayList<>();
        String accountId = user.getId();
        List<com.onesports.intelligent.k12.polarlight.domain.entity.sys.Resource> resources = resourceService.listByAccountId(user.getId(), systemCode);
        resources.stream().forEach(sysResource -> grantedAuthorities.addAll(AuthorityUtils.commaSeparatedStringToAuthorityList(String.valueOf(sysResource.getId()))));
        boolean isSuperAdmin = roleService.isSuperAdminByAccountId(accountId);
        if (SystemCodeConstants.OPERATION.equals(systemCode)) {
            orgIds = dataScopeService.listDataScopeWithOrg(accountId);
        } else if (SystemCodeConstants.ORGANIZATION.equals(systemCode)) {
            campusIds = accountService.listCampusPermission(accountId, user.getOrganizationId(), user.getStaffId());
        }

        return DomainUserDetails.builder().username(user.getPhone())
                .password(user.getPassword()).current(accountId)
                .phone(user.getPhone()).organizationId(user.getOrganizationId())
                .avatar(user.getAvatar()).gender(user.getGender())
                .nickname(user.getUsername())
                .firstTimeLogin(!user.getPasswdUpdated())
                .authorities(grantedAuthorities)
                .staffId(user.getStaffId())
                .enabled(user.getStatus())
                .superAdmin(isSuperAdmin)
                .systemCode(systemCode)
                .campusIds(campusIds)
                .dataPermissionVO(new DataPermissionVO(campusIds, orgIds))
                .build();
    }

    private Account verifyOrganization(String phone) {
        return accountService.verifyOrganization(phone);
    }


}
